import React from 'react'
import Component, { mapStateToProps, mapDispatchToProps } from '@components/Component'
import { connect } from 'react-redux'
import { Space, Checkbox, List, Spin, message, Skeleton } from 'antd'
import PropTypes from 'prop-types'
import InfiniteScroll from 'react-infinite-scroll-component'
import moment from 'moment'
import style from './CaseSelector.module.less'
import ListItem from './ListItem'
import ResultModal from './ResultModal'
import { strToNum } from '@src/assets/js/tool'

class CaseSelector extends Component {
  state = {
    height: 0,
    info: undefined,
    list: [],
    listMap: {},
    current: 1,
    total: 0,
    pageSize: 10,
    selectedIdMap: {},
    selectedList: [],
    loading: false,
    resultVisible: false
  }

  titleRef = React.createRef()

  formatDate (n) {
    n = strToNum(n)
    if (n) {
      return moment(n * 1000).format('YYYY-MM-DD HH:mm:ss')
    }
  }

  initHeight () {
    const titleRef = this.titleRef.current
    let h = 0
    let fh = 50
    if (titleRef) {
      h = titleRef.offsetHeight
    }
    if (this.props.editable) {
      fh = 150
    }
    const height = this.props.height - fh - h
    this.setState({
      height: height < 300 ? 300 : height
    })
  }

  handleInfiniteOnLoad () {
    const { pageSize, current, total, loading } = this.state
    const hasMore = pageSize * current < total
    if (!this.props.isAdding) {
      return false
    }
    if (loading || !hasMore) {
      return false // 全部加载完毕
    }
    this.getData(current + 1)
  }

  // 获取数据
  getData (current = 1) {
    const { pageSize } = this.state
    const { caseno, applicant, respondent } = this.props
    this.setState({ loading: true })
    const condition = [
      { k: 'serieno', o: 'null' }
    ]
    const params = {
      condition: JSON.stringify([...condition, ...this.props.condition]),
      page_size: pageSize,
      current
    }
    if (caseno) {
      params.caseno = caseno
    }
    if (applicant) {
      params.applicant = applicant
    }
    if (respondent) {
      params.respondent = respondent
    }
    return this.$get('/api/xapc/case', {
      params
    }).then(res => {
      this.setState({ loading: false })
      if (res.status !== 1) {
        return message.warning(res.message)
      }
      const list = this.state.list
      const l = [...list, ...res.data.list]
      this.formatMap(l)
      this.setState({
        current,
        list: l,
        total: res.data.total
      })
    }).catch(() => {
      this.setState({ loading: false })
    })
  }

  // 获取系列案列表数据
  getSeriesData () {
    this.setState({
      loading: true,
      current: 1,
      total: 0
    })
    this.$get(`/api/xapc/caseserie/${this.props.id}`)
      .then(res => {
        this.setState({ loading: false })
        if (res.status !== 1) {
          return message.warning(res.message)
        }
        const l = res.data.case
        delete res.data.case
        if (res.data.status === 0) {
          message.warning('当前系列案已取消', 2, () => {
            if (this.props.pageid && !this.props.isFromOther) {
              this.props.delWindow(this.props.pageid)
            }
          })
          return false
        }
        this.formatMap(l)
        this.setState({ list: l, info: res.data })
      }).catch(() => {
        this.setState({ loading: false })
      })
  }

  // 格式化已选项
  formatMap (list = []) {
    const m = this.state.selectedIdMap
    const lm = {}
    list.forEach(li => {
      if (m[li.id] === undefined) {
        m[li.id] = false
      }
      lm[li.id] = li
    })
    this.setState({ selectedIdMap: m, listMap: lm })
  }

  // 改变选择情况
  changeChecked (checked, d) {
    const m = this.state.selectedIdMap
    const lm = this.state.listMap
    const selectedList = []
    m[d.id] = checked
    const keys = Object.keys(m)
    keys.forEach(key => {
      if (m[key] && lm[key]) {
        selectedList.push(lm[key])
      }
    })
    this.setState({
      selectedIdMap: { ...m },
      selectedList
    })
  }

  // 根据操作状态获取数据
  getDataByStatus () {
    const { isAdding } = this.props
    if (isAdding) {
      this.getData()
    } else {
      this.getSeriesData()
    }
  }

  // 重置选择器
  resetSelector () {
    this.setState({
      selectedList: [],
      list: [],
      listMap: {},
      selectedIdMap: {}
    }, () => {
      this.getDataByStatus()
    })
  }

  // 选择全部
  checkAll () {
    const { selectedList: s, list, selectedIdMap: m } = this.state
    let l = []
    if (s.length !== list.length) {
      l = [...list]
    } else {
      l = []
    }
    const keys = Object.keys(m)
    keys.forEach(k => {
      m[k] = l.length !== 0
    })
    this.setState({
      selectedIdMap: { ...m },
      selectedList: l
    })
  }

  removeSelected (item) {
    const id = item.id
    const { selectedIdMap, selectedList } = this.state
    selectedIdMap[id] = false
    const ids = selectedList.map(li => li.id)
    const index = ids.indexOf(id)
    if (index !== -1) {
      selectedList.splice(index, 1)
    }
    const res = {
      selectedIdMap: { ...selectedIdMap },
      selectedList: [...selectedList]
    }
    if (selectedList.length === 0) {
      res.resultVisible = false
    }
    this.setState(res)
  }

  componentDidUpdate (prev) {
    if (prev.height !== this.props.height) {
      this.initHeight()
    }
    if (prev.isAdding !== this.props.isAdding) {
      this.resetSelector()
    }
    if (prev.condition !== this.props.condition) {
      this.resetSelector()
    }
    if (prev.version !== this.props.version) {
      this.resetSelector()
    }
  }

  componentDidMount () {
    this.initHeight()
    this.getDataByStatus()
  }

  renderHeader () {
    const { selectedList, list } = this.state
    const indeterminate = selectedList.length > 0 && selectedList.length !== list.length
    const checked = selectedList.length === list.length && list.length > 0
    return (
      <div className={style['list-header']}>
        <div className={style['list-th']} style={{ width: '5%' }}>
          <Checkbox indeterminate={indeterminate} checked={checked} onClick={() => this.checkAll()} />
        </div>
        <div className={style['list-th']} style={{ width: '10%' }}>收案号</div>
        <div className={style['list-th']} style={{ width: '10%' }}>案号</div>
        <div className={style['list-th']} style={{ width: '10%' }}>收案日期</div>
        <div className={style['list-th']} style={{ width: '22.5%' }}>申请人</div>
        <div className={style['list-th']} style={{ width: '22.5%' }}>被申请人</div>
        <div className={style['list-th']} style={{ width: '10%' }}>秘书</div>
        <div className={style['list-th']} style={{ width: '10%' }}>操作</div>
      </div>
    )
  }

  // 渲染查看结果按钮
  renderResultBtn () {
    if (this.state.selectedList.length > 0) {
      return <span className={style['link-btn']} style={{ fontSize: '16px' }} onClick={() => this.setState({ resultVisible: true })}>查看已选</span>
    }
  }

  renderInfo () {
    if (this.props.isAdding) {
      return null
    }
    const info = this.state.info || {}
    return (
      <div className={style['title-block']} ref={this.titleRef}>
        <div className={style['title-line']}>
          <span className={style['title-line-serieno']}>{info.serieno || '无'}</span>
          <span className={style['title-line-cell']}>标签：{info.tag || '无'}</span>
          <span className={style['title-line-cell']}>备注：{info.remark || '无'}</span>
        </div>
      </div>
    )
  }

  renderFooter () {
    if (!this.props.editable) {
      return false
    }
    const { total, selectedList, list } = this.state
    return (
      <div className={style['operate-footer']}>
        <div className={style['operate-footer-left']}>
          <Space size='middle'>
            <span className={style['selected-title']}>共 {total || list.length} 项，已加载 {list.length} 项，已选择 {selectedList.length} 项</span>
            {this.renderResultBtn()}
          </Space>
        </div>
        <div className={style['operate-footer-right']}>
          <Space size='middle'>
            {this.props.renderOperateBtn(selectedList)}
          </Space>
        </div>
      </div>
    )
  }

  render () {
    const { current, pageSize, total, loading, resultVisible, selectedList, list } = this.state
    const hasMore = current * pageSize < total
    const m = this.state.selectedIdMap
    return (
      <div className={style.container}>
        <ResultModal visible={resultVisible} list={selectedList} hide={() => this.setState({ resultVisible: false })} removeSelected={(d) => this.removeSelected(d)} />
        {this.renderInfo()}
        <div className={style['list-container']}>
          {this.renderHeader()}
          <div className={style.list} id='caseSelectorList' style={{ height: this.state.height + 'px' }}>
            <InfiniteScroll
              dataLength={list.length}
              next={() => this.handleInfiniteOnLoad()}
              hasMore={!loading && hasMore}
              scrollableTarget='caseSelectorList'
              loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
            >
              <List
                dataSource={list}
                renderItem={d => {
                  return (
                    <ListItem
                      key={d.id}
                      data={d}
                      checked={m[d.id]}
                      removeAble={!this.props.isAdding}
                      removeHandle={(d) => this.props.removeHandle(d)}
                      onChange={(checked, data) => this.changeChecked(checked, data)}
                      editable={this.props.editable}
                    />
                  )
                }}
              />
            </InfiniteScroll>
          </div>
          {list.length !== 0 && loading ? (
            <div className={style['loading-box']} style={{ height: this.state.height + 'px' }}>
              <Spin />
            </div>
          ) : null}
        </div>
        {this.renderFooter()}
      </div>
    )
  }
}

CaseSelector.propTypes = {
  height: PropTypes.number,
  renderOperateBtn: PropTypes.func,
  condition: PropTypes.array,
  isAdding: PropTypes.bool,
  id: PropTypes.string,
  version: PropTypes.number,
  removeHandle: PropTypes.func,
  pageid: PropTypes.string,
  isFromOther: PropTypes.bool,
  caseno: PropTypes.string,
  applicant: PropTypes.string,
  respondent: PropTypes.string,
  editable: PropTypes.bool
}

CaseSelector.defaultProps = {
  height: 0,
  renderOperateBtn: () => {},
  condition: [],
  isAdding: false,
  id: '',
  version: Date.now(),
  removeHandle: () => {},
  pageid: '',
  isFromOther: false,
  caseno: undefined,
  applicant: undefined,
  respondent: undefined,
  editable: false
}

const mapState = mapStateToProps(function (state) {
  return {
    userInfo: state.basic.userInfo
  }
})

const mapDispatch = mapDispatchToProps(function (dispatch) {
  return {
  }
})

export default connect(mapState, mapDispatch)(CaseSelector)
